extends Node2D
class_name Weapon

@onready var sprite_2d: Sprite2D = $Sprite2D
@onready var collision: CollisionShape2D = %CollisionShape2D
@onready var cooldown_timer: Timer = $CooldownTimer
@onready var weapon_behavior: WeaponBehavior = $WeaponBehavior


var data: ItemWeapon

var is_attacking := false
var atk_start_pos: Vector2
var targets: Array[Enemy]

var closest_target: Enemy

var weapon_spread: float

func _ready() -> void:
	atk_start_pos = sprite_2d.position

func _process(_delta: float) -> void:
	if not is_attacking:
		# 如果有目标存在，更新最近的目标
		if targets.size() > 0:
			update_closest_target()
		else:
			# 没有目标时清空最近目标引用
			closest_target = null
	
	# 旋转武器朝向目标
	rotate_to_target()
	
	# 如果可以使用武器，则使用武器
	if can_use_weapon():
		use_weapon()

# 设置武器数据和属性
func setup_weapon(_data: ItemWeapon) -> void:
	self.data = _data

	# 设置碰撞检测范围半径
	collision.shape.radius = _data.stats.max_range


# 使用武器进行攻击
func use_weapon()->void:

	# 计算射击散布角度
	calculate_spread()

	# 执行攻击行为
	weapon_behavior.execute_attack()

	# 设置冷却时间并启动冷却计时器
	cooldown_timer.wait_time = data.stats.cooldown
	cooldown_timer.start()
	
# 旋转武器朝向目标
func rotate_to_target()->void:
	if is_attacking:
		# 攻击时使用自定义旋转（包含散布角度）
		rotation = get_custom_rotation_to_target()
	else:
		# 非攻击时使用标准旋转
		rotation = get_rotation_to_target()

# 获取包含散布角度的自定义旋转角度
func get_custom_rotation_to_target()->float:
	# 检查目标是否有效
	if not closest_target or not is_instance_valid(closest_target):
		return rotation
	
	# 计算朝向目标的基础角度，然后加上武器散布角度
	var rot := global_position.direction_to(closest_target.global_position).angle()
	return rot + weapon_spread


# 获取标准旋转角度（无散布）
func get_rotation_to_target()-> float:

	# 如果没有目标，返回空闲状态旋转角度
	if targets.size() == 0:
		return get_idle_rotation()
	

	# 计算朝向最近目标的角度
	var rot := global_position.direction_to(closest_target.global_position).angle()
	return rot

# 获取空闲状态的旋转角度
func get_idle_rotation()->float:

	# 根据玩家朝向决定武器朝向
	if Global.player.is_facing_right():
		return 0
	else:
		return PI


func calculate_spread()-> void:
	weapon_spread += randf_range(-1 + data.stats.accuracy, 1 - data.stats.accuracy)
	rotation += weapon_spread

func update_closest_target()->void:
	closest_target = get_closest_target()
	

func get_closest_target()->Node2D:
	if targets.size() == 0:
		return
	
	var closest_enemy := targets[0]
	var closest_distance := global_position.distance_to(closest_enemy.global_position)
	
	for i in range(1, targets.size()):
		var target: Enemy = targets[i]
		var distance := global_position.distance_to(target.global_position)
		
		if distance < closest_distance:
			closest_enemy = target
			closest_distance = distance
	
	return closest_enemy

func can_use_weapon()->bool:
	return cooldown_timer.is_stopped() and closest_target


func _on_range_area_area_entered(area: Area2D) -> void:
	targets.push_back(area)


func _on_range_area_area_exited(area: Area2D) -> void:
	targets.erase(area)
	if targets.size() == 0:
		closest_target = null
